//UDP客户端
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include "kfifo.h"

#define IP  "127.0.0.1"
#define SPORT 60000
#define SIZE  100

#define KFIFO_BUFF_SIZE	1024

kfifo_t * mykfifo;
unsigned char kfifo_buff[KFIFO_BUFF_SIZE] = {0};
unsigned char put_data = '\0';

int sockfd = 0;
socklen_t addrLength = 0;
pthread_t pid;

int unpack(kfifo_t *mykfifo);

void * Data_Process(void * addr)
{
	int ret; 
	char data;
	printf("this is pthread\r\n");

	while (1) 
	{
		ret = recvfrom(sockfd, &put_data, 1, 0,(struct sockaddr *)&addr, &addrLength);
		if ( 0 > ret )
		{
			perror("recv err");
			continue;
		}
		kFifoPut(mykfifo, &put_data, 1);
		printf("%x\r\n", put_data);
		printf("%d\r\n", kFifoLen(mykfifo));
//		kFifoPeer(mykfifo, &data, 1);
//		printf("%x\r\n", data);
	}
}

int main()
{
	//定义变量
	int ret;

	mykfifo = (kfifo_t *)malloc(sizeof(kfifo_t));
	memset(mykfifo, 0, sizeof(kfifo_t));

	if (0 > kFifoInit(mykfifo, kfifo_buff, KFIFO_BUFF_SIZE))
	{
		perror("kFifoInit error");
		return -1;
	}

	//创建socket  SOCK_DGRAM
	sockfd = socket( PF_INET, SOCK_DGRAM, 0);
	if ( 0 > sockfd )
	{
		perror("socket error");
		return -1;
	}	
	printf("create sockfd ok\r\n");

	//设置对方的地址
	struct sockaddr_in addr = {
		.sin_family = PF_INET,
		.sin_port   = htons(SPORT),
		.sin_addr   = {
			.s_addr = inet_addr(IP),
		}, 
	};
	addrLength = sizeof(addr);

	if (0 > bind(sockfd, (struct sockaddr *)&addr, addrLength))
	{
		perror("bind");
		return 0;
	}
	printf("bind ok\r\n");

	//creatr pthread to recvive data

	if (pthread_create(&pid, 0, Data_Process,(void *)&addr))
	{
		perror("create pthread error");
		return -1;
	}

	//处理消息
	while (1)
	{
		ret = unpack(mykfifo);
	}
	//关闭Socket
	close(sockfd);
	return 0;	
}


int unpack(kfifo_t *mykfifo)
{
	unsigned char get_data[17] = {'\0'};
	unsigned char peer_data[17] = {'\0'};
	int i = 0;
	char CRC = 0;
	int ret = 0;
	
	if (17 < kFifoLen(mykfifo))
	{
//		printf("this is unpack\r\n");
		if (0 > (ret = kFifoPeer(mykfifo, peer_data, 17)))
		{
			return -1;
		}

		if (0x77 != peer_data[0])
		{
			printf("frame header error\r\n");
			kFifoGet(mykfifo, get_data, 1);
			return -1;
		}

		else if (0x0c != peer_data[2])
		{
			printf("data len error\r\n");
			kFifoGet(mykfifo, get_data, 1);
			return -1;
		}

		else if (0x88 != peer_data[16])
		{
			printf("frame tail error\r\n");
			kFifoGet(mykfifo, get_data, 1);
			return -1;
		}

		for (i = 1; i < 15; i++)
		{
			CRC ^= peer_data[i];
		} 
		printf("%x", CRC);
		if ((CRC & 0xff) != peer_data[15])
		{
			printf("CRC error\r\n");
			kFifoGet(mykfifo, get_data, 1);
			return -1;
		}

		kFifoGet(mykfifo, get_data, 17);
		
		for (i = 0; i < 17; i ++)
		{
			printf("%X ",get_data[i]);
		}
		printf("\r\n");

	}
	return 0;
}
